package cnki.tpi.kbatis.config;

import cnki.tpi.kbatis.utils.DocumentUtils;
import org.dom4j.Document;
import org.dom4j.Element;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

/**
 * @ClassName XMLConfigBuilder
 * @Description
 * @Author 小黄
 * @Date 2019/11/10 11:09
 * @Version 1.0
 */
public class XMLConfigBuilder {
    private Configuration configuration;

    public XMLConfigBuilder() {
        this.configuration = new Configuration();
    }

    /**
     * 解析 inputStream 获取 根标签
     *
     * @param inputStream
     * @return
     */
    public Configuration parse(InputStream inputStream) {
        Document document = DocumentUtils.readDocument(inputStream);
        Element rootElement = document.getRootElement();
        parseConfiguration(rootElement);
        return configuration;
    }

    /**
     * 解析 <configuration/>
     *
     * @param rootElement
     */
    private void parseConfiguration(Element rootElement) {
        Element environments = rootElement.element("environments");
        parseEnvironments(environments);
        Element mappers = rootElement.element("mappers");
        parseMappers(mappers);
    }

    /**
     * 解析 mappers
     *
     * @param mappers
     */
    private void parseMappers(Element mappers) {
        //获取所以的 mapper 节点
        List<Element> mapperElements = mappers.elements("mapper");
        for (Element mapperElement : mapperElements) {
            parseMapper(mapperElement);
        }
    }

    /**
     * 解析 mapper
     *
     * @param mapperElement
     */
    private void parseMapper(Element mapperElement) {
        //获取 dao.xml 的路径 使用通配符获取所有路径
        String location = mapperElement.attributeValue("resource");
        //InputStream inputStream = Resources.getResourcesAsStream(location);
        ResourcePatternResolver resourceLoader = new PathMatchingResourcePatternResolver();
        try {
            Resource[] source = resourceLoader.getResources(location);
            if (source != null && source.length > 0) {
                for (Resource resource : source) {
                    InputStream inputStream = resource.getInputStream();
                    Document document = DocumentUtils.readDocument(inputStream);
                    XMLMapperBuilder mapperBuilder = new XMLMapperBuilder(configuration);
                    // 获取 mapper 文件的根目录
                    mapperBuilder.parse(document.getRootElement());
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * <environments/>
     *
     * @param environments
     */
    private void parseEnvironments(Element environments) {
        String defaultId = environments.attributeValue("default");
        if (defaultId == null || defaultId.equals("")) {
            return;
        }
        List<Element> elements = environments.elements();
        for (Element element : elements) {
            String id = element.attributeValue("id");
            if (defaultId.equals(id)) {
                parseDataSource(element.element("dataSource"));
            }
        }

    }

    /**
     * 解析 <dataSource/>
     *
     * @param dataSourceElement
     */
    private void parseDataSource(Element dataSourceElement) {
        String dbType = dataSourceElement.attributeValue("type");
        if ("POOLED".equals(dbType)) {
            List<Element> propertiesElements = dataSourceElement.elements();
            //5.遍历节点
            for (Element propertyElement : propertiesElements) {
                //判断节点是连接数据库的哪部分信息
                //取出name属性的值
                String name = propertyElement.attributeValue("name");
                if ("driver".equals(name)) {
                    //表示驱动
                    //获取property标签value属性的值
                    String driver = propertyElement.attributeValue("value");
                    configuration.setDriver(driver);
                }
                if ("url".equals(name)) {
                    //表示连接字符串
                    //获取property标签value属性的值
                    String url = propertyElement.attributeValue("value");
                    configuration.setUrl(url);
                }
                if ("username".equals(name)) {
                    //表示用户名
                    //获取property标签value属性的值
                    String username = propertyElement.attributeValue("value");
                    configuration.setUsername(username);
                }
                if ("password".equals(name)) {
                    //表示密码
                    //获取property标签value属性的值
                    String password = propertyElement.attributeValue("value");
                    configuration.setPassword(password);
                }
            }
        }
    }
}
